/*
 * Copyright (C) 2008 Universidade Federal de Campina Grande
 *  
 * This file is part of OurGrid. 
 *
 * OurGrid is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free 
 * Software Foundation, either version 3 of the License, or (at your option) 
 * any later version. 
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details. 
 * 
 * You should have received a copy of the GNU Lesser General Public License 
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package org.ourgrid.peer.to;

import java.util.Map;

import org.ourgrid.common.interfaces.management.WorkerManagement;
import org.ourgrid.common.interfaces.to.LocalWorkerState;
import org.ourgrid.common.spec.worker.WorkerSpec;
import org.ourgrid.reqtrace.Req;

import br.edu.ufcg.lsd.commune.identification.DeploymentID;
import br.edu.ufcg.lsd.commune.identification.ServiceID;


/**
 * Represents a reference to a local worker under this peer.
 * This reference include five objects:
 * <ul>
 * <li> A stub to the Worker interface;
 * <li> A stub to the WorkerManagement interface;
 * <li> A WorkerSpec object.
 * <li> The Worker PublicKey
 * <li> The LocalWorkerStatus
 * </ul>
 */
@Req("REQ010")
public class LocalWorker {

	private static final long serialVersionUID = 1L;

	private LocalWorkerState status;
	private WorkerSpec workerSpec;
	private WorkerManagement workerManagement;
	private ServiceID serviceID;

	public LocalWorker( WorkerSpec workerSpec, ServiceID serviceID ) {
		this.workerSpec = workerSpec;
		this.status = LocalWorkerState.CONTACTING;
		this.serviceID = serviceID;
	}

	public void setWorkerManagement(WorkerManagement workerManagement) {
		this.workerManagement = workerManagement;
	}

	/**
	 * Gets the attributes from this <code>LocalWorker</code>
	 * @return a Map from String to String
	 */
	public Map<String,String> getAttributes() {
		return this.workerSpec.getAttributes();
	}

	/**
	 * Gets the annotations from this <code>LocalWorker</code>
	 * @return a Map from String to String
	 */
	public Map<String,String> getAnnotations() {
		return this.workerSpec.getAnnotations();
	}

	/**
	 * Verifies if this <code>LocalWorker</code> is up
	 * @return true if this <code>LocalWorker</code> is up, false otherwise
	 */
	public boolean isUp() {
		return status.isUp();
	}


	/**
	 * String representation of this <code>LocalWorker</code>
	 */
	@Override
	public String toString() {
		
		return (workerManagement != null) ? workerManagement.toString()
				: "Unrecovered local worker - workerSpec: "+workerSpec;
	}

	/**
	 * Gets the <code>WorkerSpec</code> of this <code>LocalWorker</code>
	 * @return 
	 */
	public WorkerSpec getWorkerSpec() {
		return this.workerSpec;
	}

	/**
	 * Gets the <code>WorkerManagement</code> of this <code>LocalWorker</code>
	 * @return
	 */
	public WorkerManagement getWorkerManagement() {
		return workerManagement;
	}
	
	/**
	 * Changes the status of this <code>LocalWorker</code> to UP
	 * @param workerManagement The stub to the <code>WorkerManagement</code>
	 * @param recoveredWorkerID 
	 * @param publicKey The publicKey of this <code>LocalWorker</code>
	 */	
	@Req("REQ019")
	public void workerIsUp(WorkerManagement workerManagement, DeploymentID recoveredWorkerID) {
		this.status = LocalWorkerState.OWNER;
		this.workerManagement = workerManagement;
		this.serviceID = recoveredWorkerID.getServiceID();
	}
	
	/**
	 * Changes the status of this <code>LocalWorker</code> to DOWN
	 */
	@Req("REQ019")
	public void workerIsDown() {
		this.status = LocalWorkerState.CONTACTING;
		this.workerManagement = null;
	}


	/**
	 * Gets this <code>LocalWorker</code>'s status
	 * @return
	 */
	public LocalWorkerState getStatus() {
		return status;
	}

	/**
	 * Sets the status of this Worker
	 * @param status the new status
	 */
	public void setStatus(LocalWorkerState status) {
		this.status = status;
	}
	
	/**
	 * Sets the worker specification
	 * @param workerSpec the new worker specification
	 */
	public void setWorkerSpec(WorkerSpec workerSpec) {
		this.workerSpec = workerSpec;
	}
	
	/**
	 * Gets this <code>LocalWorker</code>'s <code>PublicKey</code>
	 * @return
	 */
	public String getPublicKey() {
		
		if (this.serviceID == null) {
			return null;
		}
		
		return serviceID.getPublicKey();
	}

	public ServiceID getServiceID() {
		return serviceID;
	}

}